package com.hup.sidebar.constant;

import android.accessibilityservice.AccessibilityService;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;

import com.hup.sidebar.R;
import com.hup.sidebar.SideBarApplication;
import com.hup.sidebar.androidService.MyAccessibilityService;
import com.hup.sidebar.framework.util.IconUtil;
import com.hup.sidebar.framework.util.ListUtil;
import com.hup.sidebar.framework.util.ToastUtil;
import com.hup.sidebar.model.AppConfig;
import com.hup.sidebar.model.MultiPieFunction;
import com.hup.sidebar.model.PieFunction;
import com.hup.sidebar.view.TrampolineActivity;

import java.util.ArrayList;
import java.util.List;

/**
 * @author hugan
 * @date 2022/6/6
 */
public abstract class PieFunctionConstant {
    private static final String TAG = PieFunctionConstant.class.getSimpleName();

    /**
     * 无操作,
     * 保存到 {@link MultiPieFunction}时是null
     */
    public static final int TYPE_NONE = 0;
    /**
     * 启动app
     */
    public static final int TYPE_APP = 1;
    /**
     * 模拟按键
     */
    public static final int TYPE_KEY = 2;

    public static PieFunction getNone(Context context) {
        return new PieFunction(TYPE_NONE, context.getString(R.string.func_none));
    }

    public static ArrayList<PieFunction> functions(Context context) {
        ArrayList<PieFunction> res = new ArrayList<>();
        res.add(getNone(context));
        res.add(new PieFunction(TYPE_APP, context.getString(R.string.func_app)));
        res.add(PieFunction.key(context.getString(R.string.func_key_back), R.drawable.func_back, AccessibilityService.GLOBAL_ACTION_BACK));
        res.add(PieFunction.key(context.getString(R.string.func_key_home), R.drawable.func_home, AccessibilityService.GLOBAL_ACTION_HOME));
        res.add(PieFunction.key(context.getString(R.string.func_key_recent), R.drawable.func_recents, AccessibilityService.GLOBAL_ACTION_RECENTS));
        //GLOBAL_ACTION_QUICK_SETTINGS: flyme中也打开了通知栏
        res.add(PieFunction.key(context.getString(R.string.func_key_notifications), R.drawable.func_notifications, AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS));
        return res;
    }

    /**
     * 获取function的图标,用于非全局使用的图像显示
     */
    public static Drawable getIcon(Context context, PieFunction function) {
        if (function == null || function.type == TYPE_NONE) return null;
        //
        if (function.iconId != null) return ContextCompat.getDrawable(context, function.iconId);
        if (function.type == TYPE_APP) {
            if (function.command == null) return null;
            try {
                PackageManager packageManager = context.getPackageManager();
                String packageName = function.command;
                return packageManager.getApplicationIcon(packageName);
            } catch (NameNotFoundException e) {
                ToastUtil.short_(String.format(context.getString(R.string.none_package_icon), function.command));
            }
        }
        return null;
    }

    /**
     * 初始化全局使用的function
     */
    public static void initFunctions(AppConfig appConfig) {
        Context context = SideBarApplication.getContext();
        ArrayList<PieFunction> innerFunctions = functions(context);
        for (MultiPieFunction config : appConfig.functions) {
            initFunction(config.normal, innerFunctions);
            initFunction(config.longPress, innerFunctions);
        }
        updateCachedIcon(appConfig);
    }

    private static void initFunction(PieFunction function, ArrayList<PieFunction> innerFunctions) {
        if (function == null) return;
        if (function.type == TYPE_KEY) {
            PieFunction inner = ListUtil.get(innerFunctions, pieFunction -> pieFunction.type == TYPE_KEY && pieFunction.command.equals(function.command));
            if (inner != null) {
                function.iconId = inner.iconId;
                function.keyAction = inner.keyAction;
            }
        }
    }

    /**
     * 通常每次调用时,内存只增不减;
     * 但实际上没有内存泄露,内存增加到几百M后会被释放
     */
    public static void updateCachedIcon(AppConfig appConfig) {
        Context context = SideBarApplication.getContext();
        for (MultiPieFunction config : appConfig.functions) {
            updateCachedIcon(context, config.normal, appConfig);
            updateCachedIcon(context, config.longPress, appConfig);
        }
    }

    /**
     * @param context 只能是appContext,避免activity内存泄露
     */
    public static void updateCachedIcon(Context context, PieFunction function, AppConfig appConfig) {
        if (function == null) return;
        releaseIcon(function);

        Drawable drawable = getIcon(context, function);
        //Log.i(TAG, "cachedIcon: " + function + ", src=" + drawable);
        if (drawable == null) {
            function.cachedIcon = null;
            return;
        }
        //图标大小=圆环宽度*n倍*缩放比例
        float iconSize = appConfig.pieWidth * 1.8f * appConfig.pieIconRatio / 100;
        float scale = iconSize / drawable.getIntrinsicWidth();
        int borderColor = Color.parseColor("#BBBBBBBB");
        function.cachedIcon = IconUtil.resizeIconWithStroke(drawable, scale, 2, borderColor);
    }

    public static void releaseIcon(PieFunction function) {
        if (function == null) return;
        if (function.cachedIcon != null && !function.cachedIcon.isRecycled()) {
            function.cachedIcon.recycle();
            //Log.i(TAG, "release: " + function);
        }
    }

    /**
     * 触发功能
     */
    public static void fireAction(Context context, @NonNull PieFunction function, AppConfig appConfig) {
        if (function.type == TYPE_NONE) return;
        if (function.type == TYPE_APP) {
            if (!appConfig.useTrampoline) {
                String app = function.command;
                Intent target = context.getPackageManager().getLaunchIntentForPackage(app);
                if (target != null) {
                    context.startActivity(target);
                } else {
                    //可能情况:无权限,无入口,非系统app等
                    Log.e(TAG, "onCreate: Intent为空=" + app);
                    ToastUtil.short_(String.format(context.getString(R.string.launch_app_failure), app));
                }
            } else {
                //作用 详见类注释
                TrampolineActivity.startActivityTrampoline(context, function.command);
            }
        } else if (function.type == TYPE_KEY) {
            MyAccessibilityService service = SideBarApplication.getBeanNullable(MyAccessibilityService.class);
            if (service == null) {
                ToastUtil.short_(context.getString(R.string.accessibility_stopped));
                return;
            }
            if (function.keyAction == null) {
                ToastUtil.short_(context.getString(R.string.config_error));
                return;
            }
            service.fireKey(function.keyAction);
        } else {
            ToastUtil.short_(context.getString(R.string.config_error));
        }
    }

    /**
     * 根据包名 获取启动intent
     */
    @SuppressWarnings("unused")
    public static Intent getLaunchIntentSlow(Context context, String packageName) {
        Intent query = new Intent(Intent.ACTION_MAIN);
        query.addCategory(Intent.CATEGORY_LAUNCHER);
        PackageManager packageManager = context.getPackageManager();
        List<ResolveInfo> list = packageManager.queryIntentActivities(query, 0);
        for (ResolveInfo info : list) {
            if (info.activityInfo.packageName.equals(packageName)) {
                Intent res = new Intent();
                res.setClassName(info.activityInfo.packageName, info.activityInfo.name);
                return res;
            }
        }
        return null;
    }

}
